home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beginning Mac Programming
/
Beginning Mac Programming.bin
/
Open Me for REALbasic 3
/
REALbasic 3.2
/
Example Projects
/
Techniques
/
Examples by Thomas Tempelmann
/
TT's FileMgr-Plugin
/
Source Code (CW Pro 3)
/
Plugin Source.cpp
< prev
Wrap
Text File
|
1999-07-03
|
8KB
|
303 lines
/*
* REALbasic-Plugin that provides some useful Volume- and File-related functions.
*
* MacOS-only! (not useful under Windows or Java)
* The enclosed project file was created using CodeWarrior Pro 3.
*
* This code is freeware, you may use and extend it as you like.
* Created March 8, 99 by Thomas Tempelmann.
* More RB-related stuff can be found here: <http://www.tempel.org/rb>
*
* Revision history
* ----------------
* March 14, 99
* Added VolResolveID()
* March 26, 99
* Added the methods SetFileFlags, Set/GetFolderFlags,
* VolGetFolderItemID and VolResolveID.
*
* Enjoy and contribute!
*/
#include <string.h>
#include "rb_plugin.h"
static long IsOnRemoteVolume (REALfolderItem volIn)
// returns true if the specified file, folder or volume is not local but
// on a File Sharing Server
{
FSSpec fsSpec;
if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
IOParam pb;
GetVolParmsInfoBuffer buf;
pb.ioVRefNum = fsSpec.vRefNum;
pb.ioBuffer = (Ptr)&buf;
pb.ioReqCount = 14;
pb.ioNamePtr = nil;
if (PBHGetVolParmsSync ((HParmBlkPtr)&pb) == noErr && pb.ioActCount >= 14) {
if (buf.vMLocalHand != 0) return 1;
}
}
return 0;
}
static long VolGetVRefNum (REALfolderItem volIn)
// returns the (negative) volume reference number of a file, folder or volume
{
FSSpec fsSpec;
if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
return fsSpec.vRefNum;
}
return 0;
}
static REALfolderItem VolumeByVRefNum (long vRefNum)
// returns a FolderItem that points to the root directory
// of the specific volume reference number. nil is returned if
// the volume reference number was not valid.
{
FSSpec spec;
FSMakeFSSpec (vRefNum, fsRtDirID, "\p", &spec);
return REALFolderItemFromFSSpec (&spec);
}
static long GetFileFlags (REALfolderItem f)
// if the returned value is negative, an error has occured and the Attribute is not valid
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
FInfo fi;
err = FSpGetFInfo (&fsSpec, &fi);
if (!err) return fi.fdFlags;
}
return err;
}
static long SetFileFlags (REALfolderItem f, long flags)
// returns errors code
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
FInfo fi;
err = FSpGetFInfo (&fsSpec, &fi);
if (!err) {
fi.fdFlags = flags;
err = FSpSetFInfo (&fsSpec, &fi);
}
}
return err;
}
static long GetFolderFlags (REALfolderItem f)
// if the returned value is negative, an error has occured and the Attribute is not valid
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = fsSpec.name;
pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
pb.hFileInfo.ioDirID = fsSpec.parID;
pb.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync (&pb);
if (!err) return pb.dirInfo.ioDrUsrWds.frFlags;
}
return err;
}
static long SetFolderFlags (REALfolderItem f, long flags)
// returns errors code
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = fsSpec.name;
pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
pb.hFileInfo.ioDirID = fsSpec.parID;
pb.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync (&pb);
if (!err) {
pb.dirInfo.ioDrUsrWds.frFlags = flags;
pb.hFileInfo.ioDirID = fsSpec.parID;
err = PBSetCatInfoSync (&pb);
}
}
return err;
}
static long GetFileAttribute (REALfolderItem f)
// returns an Integer with the following bits to test for:
// 0: locked
// 2: rsrc fork open
// 3: data fork open
// 4: is directory
// 7: file (one or both forks) is open
// if the returned value is negative, an error has occured and the Attribute is not valid
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
HFileParam pb;
pb.ioVRefNum = fsSpec.vRefNum;
pb.ioFVersNum = 0;
pb.ioFDirIndex = 0;
pb.ioDirID = fsSpec.parID;
pb.ioNamePtr = fsSpec.name;
err = PBHGetFInfoSync ((HParmBlkPtr)&pb);
if (!err) return (long)(unsigned char) pb.ioFlAttrib;
}
return err;
}
static long IsFileOpen (REALfolderItem f)
// returns true if file is open, returns false if it is not open or not a file
{
long l = GetFileAttribute (f);
return (l >= 0) && ((l & 0x8C) != 0);
}
static long IsRsrcOpen (REALfolderItem f)
// returns true if file's rsrc fork is open, returns false if it is not open or not a file
{
long l = GetFileAttribute (f);
return (l >= 0) && ((l & 0x04) != 0);
}
static REALfolderItem VolResolveIDByVRefNum (long vRefNum, long id)
{
FSSpec spec;
OSErr err;
if (vRefNum >= 0 || id == 0) return nil;
err = FSMakeFSSpec (vRefNum, id, "\p", &spec);
if (err) {
FIDParam pb;
pb.ioVRefNum = vRefNum;
pb.ioNamePtr = spec.name;
pb.ioFileID = id;
err = PBResolveFileIDRefSync ((HParmBlkPtr)&pb);
if (err) {
return nil;
}
spec.vRefNum = vRefNum;
spec.parID = pb.ioSrcDirID;
}
return REALFolderItemFromFSSpec (&spec);
}
static REALfolderItem VolResolveIDByFolderItem (REALfolderItem vol, long id)
{
return VolResolveIDByVRefNum (VolGetVRefNum (vol), id);
}
static long VolGetFolderItemID (REALfolderItem f, long createFileID)
// returns 0 if an error occured
{
FSSpec fsSpec;
OSErr err = -1;
if (REALFSSpecFromFolderItem (&fsSpec, f)) {
long theID;
Boolean isDir;
{
CInfoPBRec pb;
pb.hFileInfo.ioNamePtr = fsSpec.name;
pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
pb.hFileInfo.ioDirID = fsSpec.parID;
pb.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync (&pb);
theID = pb.hFileInfo.ioDirID; // a fileID/dirID is never 0
isDir = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0;
}
if (!err) {
if (createFileID && !isDir) {
FIDParam pb;
pb.ioVRefNum = fsSpec.vRefNum;
pb.ioNamePtr = fsSpec.name;
pb.ioSrcDirID = fsSpec.parID;
err = PBCreateFileIDRefSync ((HParmBlkPtr)&pb);
if (err && err != fidExists) return 0; // error, could not create the FileID
theID = pb.ioFileID;
}
return theID;
}
}
return 0;
}
static REALfolderItem myNewFolderItem (const FSSpec* spec)
{
return REALFolderItemFromFSSpec (spec);
}
static REALfolderItem NewFolderItem (long vRefNum, long parID, REALstring name)
// returns nil if an error occured
{
FSSpec spec;
FSMakeFSSpec(vRefNum, parID, REALPString(name), &spec);
return myNewFolderItem (&spec);
}
typedef struct {
char unknown[24];
long size;
Ptr dataPtr;
} RBMemoryBlock;
static REALfolderItem NewFolderItemFromFSSpecAsMemBlk (RBMemoryBlock* fsSpec)
// returns nil if an error occured
{
if (fsSpec == NULL) {
return nil;
}
return myNewFolderItem ((FSSpec*)fsSpec->dataPtr);
}
REALexport pluginExports[] = {
{ nil, IsOnRemoteVolume },
{ nil, VolGetVRefNum },
{ nil, VolumeByVRefNum },
{ nil, GetFileFlags },
{ nil, SetFileFlags },
{ nil, GetFolderFlags },
{ nil, SetFolderFlags },
{ nil, GetFileAttribute },
{ nil, IsFileOpen },
{ nil, IsRsrcOpen },
{ nil, VolResolveIDByVRefNum },
{ nil, VolResolveIDByFolderItem },
{ nil, VolGetFolderItemID },
{ nil, NewFolderItem },
{ nil, NewFolderItemFromFSSpecAsMemBlk },
};
short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport);
REALmethodDefinition methods[] = {
{0, "IsOnRemoteVolume(fileOrFolder as FolderItem) as Boolean"},
{1, "VolGetVRefNum(fileOrFolder as FolderItem) as Integer"},
{2, "VolumeByVRefNum(vRefNum as Integer) as FolderItem"},
{3, "GetFileFlags(file as FolderItem) as Integer"},
{4, "SetFileFlags(file as FolderItem, flags as Integer) as Integer"},
{5, "GetFolderFlags(folder as FolderItem) as Integer"},
{6, "SetFolderFlags(folder as FolderItem, flags as Integer) as Integer"},
{7, "GetFileAttribute(file as FolderItem) as Integer"},
{8, "IsFileOpen(file as FolderItem) as Boolean"},
{9, "IsResourceForkOpen(file as FolderItem) as Boolean"},
{10,"VolResolveID(vRefNum as Integer, id as Integer) as FolderItem"},
{11,"VolResolveID(vol as FolderItem, id as Integer) as FolderItem"},
{12,"VolGetFolderItemID(item as FolderItem, createFileIDs as Boolean) as Integer"},
{13,"NewFolderItem(vRefNum as Integer, parID as Integer, name as String) as FolderItem"},
{14,"NewFolderItemFromFSSpec(fsSpec as MemoryBlock) as FolderItem"},
};
void PluginEntry (void)
{
for (int i = 0; i < pluginExportCode; ++i) {
REALRegisterMethod (&methods[i]);
}
}